{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% load bootstrap3 %}

{% block custom_head_css_js %}
    <link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
    <link rel="stylesheet" href="{% static 'js/plugins/xterm/xterm.css' %}"/>
    <link href="{% static 'css/plugins/codemirror/codemirror.css' %}" rel="stylesheet">
    <link href="{% static 'css/plugins/codemirror/ambiance.css' %}" rel="stylesheet">
    <script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.exhide.min.js' %}"></script>
    <script src="{% static 'js/jquery.form.min.js' %}"></script>
    <script src="{% static 'js/plugins/xterm/xterm.js' %}"></script>
    <script src="{% static 'js/plugins/xterm/addons/fit/fit.js' %}"></script>
    <script src="{% static 'js/plugins/codemirror/codemirror.js' %}"></script>
    <script src="{% static 'js/plugins/codemirror/mode/shell/shell.js' %}"></script>
    <style type="text/css">
        .xterm .xterm-screen canvas {
            position: absolute;
            left: 0;
            top: 0;
            padding: 10px;
        }

        .select2-container .select2-selection--single {
            height: 34px;
        }

        .terminal .xterm-viewport {
            background-color: #1f1b1b;
            overflow: auto;
        }

        #term ::-webkit-scrollbar-track {
            -webkit-box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.3);
            background-color: #272323;
            border-radius: 6px;
        }

        #term ::-webkit-scrollbar {
            width: 8px;
            height: 8px;
        }

        #term ::-webkit-scrollbar-thumb {
            background-color: #494141;
            border-radius: 6px;
        }
    </style>
{% endblock %}

{% block content %}
    <div class="wrapper wrapper-content">
        <div class="row">
            <div class="col-sm-3" id="split-left" style="padding-left: 3px;overflow:auto">
                <div class="ibox treebox float-e-margins">
                    <div class="ibox-content mailbox-content"
                         style="padding-top: 0;padding-left: 1px">
                        <div class="file-manager ">
                            <div id="assetTree" class="ztree">
                                {% trans 'Loading' %} ..
                            </div>
                            <div class="clearfix"></div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-sm-9 animated fadeInRight" id="split-right">
                <div class="tree-toggle">
                    <div class="btn btn-sm btn-primary tree-toggle-btn" onclick="toggle()">
                        <i class="fa fa-angle-left fa-x" id="toggle-icon"></i>
                    </div>
                </div>
                <div class="mail-box-header" style="padding-top: 5px;">
                    <form enctype="multipart/form-data" method="post" class="form-horizontal" action="" onsubmit="return execute()">
                        <div class="form-group">
                            <div id="term" style="height: 100%;width: 100%"></div>
                        </div>
                        <div class="row">
                            <div class="col-sm-10">
                                <div class="input-group" style="height: 100%; width: 100%">
                                    <textarea class="form-control" id="command-text"></textarea>
                                </div>
                            </div>
                            <div class="col-sm-2">
                                <select class="select2 form-control" id="system-users-select">
                                    {% for s in system_users %}
                                        <option value="{{ s.id }}" {% if s.login_mode == 'manual' or s.protocol in 'mysql|telnet|vnc'%}disabled{% endif %}>{{ s }}</option>
                                    {% endfor %}
                                </select>
                                <button type="button" class="btn btn-primary btn-execute" style="margin-top: 30px; width: 100%">
                                    {% trans 'Go' %}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

{% block custom_foot_js %}
<script>
    var zTree, show = 0;
    var systemUserId = null;
    var url = null;
    var treeUrl = "{% url 'api-perms:my-nodes-with-assets-as-tree' %}?cache_policy=1";

    function initTree() {
        $('#assetTree').html("{% trans 'Loading' %}" + '..');
        if (systemUserId) {
            url = treeUrl + '&system_user=' + systemUserId
        } else {
            url = treeUrl
        }
        var setting = {
            check: {
                enable: true
            },
            view: {
                dblClickExpand: false,
                showLine: true
            },
            data: {
                simpleData: {
                    enable: true
                }
            },
            edit: {
                enable: true,
                showRemoveBtn: false,
                showRenameBtn: false,
                drag: {
                    isCopy: true,
                    isMove: true
                }
            },
            callback: {
                onCheck: onCheck,
                onClick: onClick,
            }
        };

        $.get(url, function (data, status) {
            $.fn.zTree.init($("#assetTree"), setting, data);
            zTree = $.fn.zTree.getZTreeObj("assetTree");
            rootNodeAddDom(zTree, function () {
                treeUrl = treeUrl.replace('cache_policy=1', 'cache_policy=2');
                initTree();
            });
        });
    }
    function onClick(event, treeId, treeNode, clickFlag){
        if (treeNode.meta.type === 'asset'){
            let protocolsStr = treeNode.meta.asset.protocols + '';
            if (protocolsStr.indexOf('ssh/') === -1){
                toastr.warning("{% trans "Asset configuration does not include the SSH protocol" %}");
            }
        }
    }
    function getSelectedAssetsNode() {
        var nodes = zTree.getCheckedNodes(true);
        var assetsNodeId = [];
        var assetsNode = [];
        nodes.forEach(function (node) {
            if (node.meta.type === 'asset' && !node.isHidden) {
                var protocolsStr = node.meta.asset.protocols + '';
                if (assetsNodeId.indexOf(node.id) === -1 && protocolsStr.indexOf('ssh') > -1){
                    assetsNodeId.push(node.id);
                    assetsNode.push(node)
                }
            }
        });
        return assetsNode;
    }
    function onCheck(e, treeId, treeNode) {
        var nodes = getSelectedAssetsNode();
        var nodes_names = nodes.map(function (node) {
            return node.name;
        });
        var message = "{% trans 'Selected assets' %}" + ': ';
        message += nodes_names.join(", ");
        message += "\r\n";
        message += "{% trans 'In total' %}" + ': ' + nodes_names.length + "个\r\n";
        term.clear();
        term.write(message)
    }

    function toggle() {
        if (show === 0) {
            $("#split-left").hide(500, function () {
                $("#split-right").attr("class", "col-sm-12");
                $("#toggle-icon").attr("class", "fa fa-angle-right fa-x");
                show = 1;
            });
        } else {
            $("#split-right").attr("class", "col-sm-9");
            $("#toggle-icon").attr("class", "fa fa-angle-left fa-x");
            $("#split-left").show(500);
            show = 0;
        }
    }

    var term = null;
    var ws = null;

    function initResultTerminal() {
        term = new Terminal({
            cursorBlink: false,
            screenKeys: false,
            fontFamily: 'monaco, Consolas, "Lucida Console", monospace',
            fontSize: 13,
            rightClickSelectsWord: true,
            disableStdin: true,
            lineHeight: 1.2,
            theme: {
                background: '#1f1b1b'
            }
        });
        term.open(document.getElementById('term'));
        var msg = "{% trans 'Select the left asset, select the running system user, execute command in batch' %}" + "\r\n";
        window.fit.fit(term);
        {#fit(term);#}
        term.write(msg);

        var scheme = document.location.protocol === "https:" ? "wss" : "ws";
        var port = document.location.port ? ":" + document.location.port : "";
        var url = "/ws/ops/tasks/log/";
        var wsURL = scheme + "://" + document.location.hostname + port + url;
        var failOverPort = "{{ ws_port }}";
        var failOverWsURL = scheme + "://" + document.location.hostname + ':' + failOverPort + url;
        ws = new WebSocket(wsURL);
        ws.onerror = function (e) {
            ws = new WebSocket(failOverWsURL);
            ws.onmessage = function(e) {
                var data = JSON.parse(e.data);
                term.write(data.message);
            };
            ws.onerror = function (e) {
                term.write("Connect websocket server error")
            }
        };
        ws.onmessage = function(e) {
            var data = JSON.parse(e.data);
            term.write(data.message);
        };
    }

    function wrapperError(msg) {
        return '\033[31m' + msg + '\033[0m' + '\r\n';
    }

    function execute() {
        if (!term) {
            initResultTerminal()
        }
        var size = 'rows=' + term.rows + '&cols=' + term.cols;
        var url = '{% url "api-ops:command-execution-list" %}?' + size;
        var run_as = systemUserId;
        var command = editor.getValue();
        var hosts = getSelectedAssetsNode().map(function (node) {
            return node.id;
        });
        if (hosts.length === 0) {
            term.write(wrapperError("{% trans 'Unselected assets' %}"));
            return
        }
        if (!command) {
            term.write(wrapperError("{% trans 'No input command' %}"));
            return
        }
        if (!run_as) {
            term.write(wrapperError("{% trans 'No system user was selected' %}"));
            return
        }
        var data = {
            hosts: hosts,
            run_as: run_as,
            command: command
        };

        function writeExecutionOutput(taskId) {
            var msg = "{% trans 'Pending' %} ";
            term.write(msg);
            msg = JSON.stringify({task: taskId});
            ws.send(msg);
        }

        requestApi({
            url: url,
            body: JSON.stringify(data),
            method: 'POST',
            flash_message: false,
            success: function (resp) {
                {#log_url = resp.log_url;#}
                writeExecutionOutput(resp.id)
            }
        });
        return false;
    }

    var editor;
    $(document).ready(function () {
        $('.treebox').css('height', window.innerHeight - 60);
        systemUserId = $('#system-users-select').val();

        $(".select2").select2({
            dropdownAutoWidth: true,
        }).on('select2:select', function (evt) {
            var data = evt.params.data;
            systemUserId = data.id;
            initTree();
        });
        editor = CodeMirror.fromTextArea(document.getElementById("command-text"), {
            lineNumbers: true,
            lineWrapping: true,
            mode: "shell"
        });
        editor.setSize(600, 100);
        var charWidth = editor.defaultCharWidth(), basePadding = 4;
        editor.on("renderLine", function (cm, line, elt) {
            var off = CodeMirror.countColumn(line.text, null, cm.getOption("tabSize")) * charWidth;
            elt.style.textIndent = "-" + off + "px";
            elt.style.paddingLeft = (basePadding + off) + "px";
        });
        editor.refresh();
        initTree();
        initResultTerminal();
    }).on('click', '.btn-execute', function () {
        execute()
    })
</script>
{% endblock %}
